package cn.schoolwow.flow.monitor.module.business.flowLog.flow;

import cn.schoolwow.ams.module.block.listBlock.common.domain.operation.ListBlockRequest;
import cn.schoolwow.flow.monitor.domain.handler.FlowMonitorFlowMappingHandler;
import cn.schoolwow.flow.monitor.domain.FlowMonitorOption;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.domain.FlowDataFeature;
import cn.schoolwow.quickflow.dto.FlowContextDataRange;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.quickflow.flow.CompositeBusinessFlow;
import cn.schoolwow.util.domain.query.queryPackage.QueryPackage;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.context.ApplicationContext;

import java.util.List;

public class ExecuteFlowCommonFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        ListBlockRequest listBlockRequest = flowContext.checkInstanceData(ListBlockRequest.class);

        JSONArray array = new JSONArray();
        if(null!=listBlockRequest.array){
            array.addAll(listBlockRequest.array);
        }else{
            array.add(listBlockRequest.row);
        }
        for(int i=0;i<array.size();i++){
            JSONObject o = array.getJSONObject(i);
            String name = o.getString("name");
            JSONObject requestData = o.getJSONObject("requestData");

            if(executeByCompositeBusinessFlow(name, requestData, flowContext)){
                continue;
            }
            if(executeByBusinessFlow(name, requestData, flowContext)){
                continue;
            }
            throw new IllegalArgumentException("流程不存在!名称:"+name);
        }
    }

    @Override
    public String name() {
        return "执行流程";
    }

    private boolean executeByCompositeBusinessFlow(String name, JSONObject requestData, FlowContext flowContext){
        ApplicationContext applicationContext = flowContext.checkInstanceData(ApplicationContext.class);
        FlowMonitorFlowMappingHandler flowMonitorFlowMappingHandler = applicationContext.getBean(FlowMonitorFlowMappingHandler.class);
        FlowMonitorOption flowMonitorOption = flowContext.checkInstanceData(FlowMonitorOption.class);

        CompositeBusinessFlow compositeBusinessFlow = flowMonitorFlowMappingHandler.getCompositeBusinessFlow(name);
        if(null==compositeBusinessFlow) {
            List<CompositeBusinessFlow> compositeBusinessFlowList = QueryPackage.newQuery(flowMonitorOption.basePackageName)
                    .addClassQuery(CompositeBusinessFlow.class)
                    .execute()
                    .getInstanceList(CompositeBusinessFlow.class);
            if(null!=compositeBusinessFlowList&&!compositeBusinessFlowList.isEmpty()){
                for(CompositeBusinessFlow compositeBusinessFlow1:compositeBusinessFlowList){
                    String currentName = compositeBusinessFlow1.name();
                    if(name.equalsIgnoreCase(currentName)){
                        compositeBusinessFlow = compositeBusinessFlow1;
                        break;
                    }
                }
            }

        }
        if(null==compositeBusinessFlow){
            return false;
        }
        flowMonitorOption.logQuickFlow.startFlow(compositeBusinessFlow)
                .putFlowContextDataMap(requestData, FlowContextDataRange.Flow, FlowDataFeature.RequestData)
                .execute();
        return true;
    }

    private boolean executeByBusinessFlow(String name, JSONObject requestData, FlowContext flowContext){
        ApplicationContext applicationContext = flowContext.checkInstanceData(ApplicationContext.class);
        FlowMonitorFlowMappingHandler flowMonitorFlowMappingHandler = applicationContext.getBean(FlowMonitorFlowMappingHandler.class);
        FlowMonitorOption flowMonitorOption = flowContext.checkInstanceData(FlowMonitorOption.class);

        BusinessFlow businessFlow = flowMonitorFlowMappingHandler.getFlow(name);
        if(null==businessFlow) {
            List<BusinessFlow> businessFlowList = QueryPackage.newQuery(flowMonitorOption.basePackageName)
                    .addClassQuery(BusinessFlow.class)
                    .execute()
                    .getInstanceList(BusinessFlow.class);
            if(null!=businessFlowList&&!businessFlowList.isEmpty()){
                for(BusinessFlow businessFlow1:businessFlowList){
                    String currentBusinessName = businessFlow1.name();
                    if(name.equalsIgnoreCase(currentBusinessName)){
                        businessFlow = businessFlow1;
                        break;
                    }
                }
            }
        }
        if(null==businessFlow){
            return false;
        }
        flowMonitorOption.logQuickFlow.startFlow(businessFlow)
                .putFlowContextDataMap(requestData, FlowContextDataRange.Flow, FlowDataFeature.RequestData)
                .execute();
        return true;
    }
}
